package com.jc.softinput;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final boolean DEBUG = true;
    private static final String TAG = "MainActivity";
    /*软键盘最小高度,这个的来源有点有点奇怪*/
    private static final int SOFT_KEY_BOARD_MIN_HEIGHT = 150;
    private static final int DELAY_BEFORE_HIDE_ATTACHMENT = 400; // ms
    private boolean mIsSoftInputShown = false;
    /* 软键盘的初始化高度,可以根据不同分辨率分别指定*/
    private int mSoftInputHeight = 554;
    /*假设该界面是类似微信的附件界面，包含拍照、录像等入口*/
    private LinearLayout mAttachmentPanel;
    private Handler mUiHandler;
    private ImageButton mImageButton;
    private EditText mTextEditor;
    /*聊天内容界面通常是以ListView的形式呈现*/
    private TextView mContentPanel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContentPanel = (TextView)findViewById(R.id.contentPanel);
        mContentPanel.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                setSoftInputAdjustResize();
                mAttachmentPanel.setVisibility(View.GONE);
                hideSoftInputMethod();
                return true;
            }
        });
        mUiHandler = new Handler(Looper.getMainLooper());
        /*初始化附件的高度，这里通常设置为272dp*/
        mSoftInputHeight = getResources().getDimensionPixelSize(R.dimen.init_soft_input_height);
        mAttachmentPanel = (LinearLayout)findViewById(R.id.attachment_panel);
        setAttachmentPanelHeight();
        mImageButton = (ImageButton)findViewById(R.id.img);
        mImageButton.setOnClickListener(this);
        mTextEditor = (EditText)findViewById(R.id.editText);
        mTextEditor.setFocusable(true);
        mTextEditor.setFocusableInTouchMode(true);
        mTextEditor.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean hasFocus) {
                if (DEBUG) Log.d(TAG, "mTextEditor hasFocus: " + hasFocus);
                /* 输入框获取到焦点之后，弹起了软键盘，这个时候如果附件是可见的，说明软键盘是以覆盖的形式出现的，我们延迟 0.4 s之后，
                    先把软键盘呈现的方式设置成往上顶，然后偷偷的把附件隐藏，神不知鬼不觉，非常友好的让软键盘接替了附件。
                 */
                if (hasFocus) {
                    if (View.VISIBLE == mAttachmentPanel.getVisibility()) {
                        mUiHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (DEBUG)Log.d(TAG, "hide attachment panel");
                                setSoftInputAdjustResize();
                                mAttachmentPanel.setVisibility(View.GONE);
                            }
                        }, DELAY_BEFORE_HIDE_ATTACHMENT);
                    }
                }
            }
        });
        mImageButton.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (DEBUG) Log.d(TAG, "mImageButton hasFocus: " + hasFocus);
                if (hasFocus) {
                    onClick(mImageButton);
                }
            }
        });
        HeightChangedLinearLayout heightChangedLinearLayout = (HeightChangedLinearLayout)findViewById(R.id.height_change_layout);
        heightChangedLinearLayout.setListener(new HeightChangedLinearLayout.LayoutSizeChangedListener() {
            @Override
            public void onLayoutSizeChanged(int w, int h, int oldw, int oldh) {
                int softInputHeight = mSoftInputHeight;
                Log.d(TAG, "h: " + h + ", oldh: " + oldh);
                if (h - oldh >  SOFT_KEY_BOARD_MIN_HEIGHT) {
                    mIsSoftInputShown = false;
                } else {
                    /* 获取到软键盘的高度*/
                    softInputHeight = Math.abs(h - oldh);
                    mIsSoftInputShown = true;
                }
                Log.d(TAG, "onLayoutSizeChanged, mIsSoftInputShown: " + mIsSoftInputShown);
                if (softInputHeight != mSoftInputHeight) {
                    if (DEBUG)Log.d(TAG, "New mSoftInputHeight: " + softInputHeight);
                    mSoftInputHeight = softInputHeight;
                    /*更新附件的高度*/
                    mUiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            setAttachmentPanelHeight();
                        }
                    });
                }
            }
        });
    }

    /* 重新计算附件的高度*/
    private void setAttachmentPanelHeight() {
        ViewGroup.LayoutParams layoutParams = mAttachmentPanel.getLayoutParams();
        layoutParams.height = mSoftInputHeight;
        mAttachmentPanel.setLayoutParams(layoutParams);
    }

    /* 隐藏收入法 */
    private void hideSoftInputMethod() {
        InputMethodManager im = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mAttachmentPanel.getVisibility() == View.VISIBLE) {
            setSoftInputAdjustResize();
            mAttachmentPanel.setVisibility(View.GONE);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /*软键盘以覆盖当前界面的形式出现*/
    private void setSoftInputAdjustNothing(){
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
    }

    /*软键盘以顶起当前界面的形式出现, 注意这种方式会使得当前布局的高度发生变化，触发当前布局onSizeChanged方法回调，这里前后高度差就是软键盘的高度了*/
    private void setSoftInputAdjustResize(){
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }

    @Override
    public void onClick(View view) {
        if (view == mImageButton) {
            Log.d(TAG, "mIsSoftInputShown: " + mIsSoftInputShown  + ", visible: " + mAttachmentPanel.getVisibility());
            if (mIsSoftInputShown) {
                /*软键盘存在，但附件不存在的时候，显示附件，隐藏软键盘，设置下一次出现方式为覆盖 */
                if (mAttachmentPanel.getVisibility() == View.GONE) {
                    mAttachmentPanel.setVisibility(View.VISIBLE);
                    hideSoftInputMethod();
                    mTextEditor.clearFocus();
                    setSoftInputAdjustNothing();
                } else {
                    /* 在用户点击弹附件按钮的时候，附件和软键盘同时存在的可能性很小,只隐藏软键盘吧 */
                    setSoftInputAdjustResize();
                    hideSoftInputMethod();
                }
            } else { /* 软键盘不存在 */
                if (mAttachmentPanel.getVisibility() == View.GONE) {
                    mTextEditor.clearFocus();
                    setSoftInputAdjustNothing();
                    mAttachmentPanel.setVisibility(View.VISIBLE);
                } else {
                    mAttachmentPanel.setVisibility(View.GONE);
                    setSoftInputAdjustResize();
                }
            }
        }
    }
}
